<template>
  <div class="app-container">
    <!--工具栏-->
    <div class="crud-group">
      <!-- 搜索 -->
      <template>
        <el-select
          v-model="query.dbName"
          filterable
          clearable
          placeholder="库名称搜索"
        >
          <el-option
            v-for="item in databaseList"
            :key="item"
            :label="item"
            :value="item"
          />
        </el-select>
      </template>
      <template>
        <el-select
          v-model="query.tableName"
          filterable
          clearable
          placeholder="表名称搜索"
        >
          <el-option
            v-for="item in tableList"
            :key="item"
            :label="item"
            :value="item"
          />
        </el-select>
      </template>
      <template>
        <el-select
          v-model="query.desensitizeFunction"
          filterable
          clearable
          placeholder="脱敏函数搜索"
        >
          <el-option
            v-for="item in functionList"
            :key="item"
            :label="item"
            :value="item"
          />
        </el-select>
      </template>
      <template>
        <el-select
          v-model="query.fieldName"
          filterable
          clearable
          placeholder="脱敏字段搜索"
        >
          <el-option
            v-for="item in fieldList"
            :key="item"
            :label="item"
            :value="item"
          />
        </el-select>
      </template>
      <rrOperation :crud="crud" />
      <el-button
        type="primary"
        icon="el-icon-refresh-left"
        :loading="resetting"
        @click="reset"
      >刷新
      </el-button>
    </div>
    <div style="margin-bottom: 10px">
      <el-button
        class="filter-item"
        icon="el-icon-plus"
        size="mini"
        type="primary"
        @click="initAllFunctionList();crud.toAdd()"
      >新增</el-button>
      <div style="display: inline-block;margin-left: 10px">
        <el-button
          v-if="crud.optShow.del"
          slot="reference"
          v-permission="permission.del"
          class="filter-item"
          type="danger"
          icon="el-icon-delete"
          size="mini"
          :loading="disableLoading"
          :disabled="crud.selections.length === 0"
          @click="toDelete(crud.selections)"
        >禁用
        </el-button>
      </div>
      <div style="display: inline-block; margin-left: 10px">
        <el-button
          type="primary"
          icon="el-icon-tickets"
          size="mini"
          @click="showDesensitizationFuncation"
        >脱敏函数清单
        </el-button>
      </div>
      <div style="display: inline-block; margin-left: 10px">
        <el-button
          type="primary"
          icon="el-icon-tickets"
          size="mini"
          @click="showDesensitizationMap"
        >脱敏函数与字段映射
        </el-button>
      </div>
      <div style="display: inline-block; margin-left: 10px">
        <el-button
          type="primary"
          icon="el-icon-tickets"
          size="mini"
          @click="showDesensitizationBlackFuncation"
        >脱敏黑名单
        </el-button>
      </div>
    </div>
    <!--表格渲染-->
    <el-table
      ref="table"
      v-loading="crud.loading"
      :data="crud.data"
      border
      @select="crud.selectChange"
      @select-all="crud.selectAllChange"
      @selection-change="crud.selectionChangeHandler"
    >
      <el-table-column
        type="selection"
        width="40"
      />
      <el-table-column label="库表名称">
        <template slot-scope="scope">
          {{ scope.row.dbName + "." + scope.row.tableName }}
        </template>
      </el-table-column>
      <el-table-column
        label="字段名称"
        prop="fieldName"
      />
      <el-table-column
        label="脱敏函数"
        prop="desensitizeFunction"
        width="240px"
      />
      <el-table-column
        label="创建人"
        prop="createBy"
        width="100px"
      />
      <el-table-column
        label="创建时间"
        prop="createTime"
        width="150px"
      />
      <el-table-column
        fixed="right"
        label="验证"
        width="80px"
      >
        <template slot-scope="scope">
          <el-button
            type="text"
            @click="toShowSimple(scope.row)"
          >验证</el-button>
        </template>
      </el-table-column>
    </el-table>
    <div style="float: right">
      <!--分页组件-->
      <pagination />
    </div>
    <el-dialog
      :close-on-click-modal="false"
      :before-close="crud.cancelCU"
      :visible.sync="crud.status.add > 0"
      title="新增脱敏字段"
      width="500px"
      append-to-body
    >
      <el-form
        ref="form"
        :model="form"
        :rules="rules"
        :inline="true"
        label-width="120px"
      >
        <el-form-item
          label="脱敏字段"
          prop="fieldName"
        >
          <el-input
            v-model="form.fieldName"
            clearable
            size="small"
            style="width: 300px"
            placeholder="请输入脱敏字段"
          />
        </el-form-item>
        <el-form-item
          label="脱敏函数"
          prop="functionId"
        >
          <el-select
            v-model="form.functionId"
            :disabled="form.fieldName === null"
            style="width: 300px"
            @change="functionNameChange"
          >
            <el-option
              v-for="item in desensitizationFuncationList"
              :key="item.id"
              :label="item.functionExplain"
              :value="item.id"
            />
          </el-select>
        </el-form-item>
        <el-form-item
          label="脱敏函数样例"
          prop="desensitizeFunction"
        >
          <el-input
            v-model="form.desensitizeFunction"
            clearable
            size="small"
            :disabled="form.fieldName === null"
            style="width: 300px"
            type="textarea"
            :rows="3"
            placeholder="请输入脱敏函数描述"
          />
        </el-form-item>
        <div
          class="dialog-footer"
          style="width:100%;text-align: center"
        >
          <el-button @click="crud.cancelCU">关 闭</el-button>
          <el-button
            type="primary"
            @click="crud.submitCU"
          >保 存</el-button>
        </div>
      </el-form>
    </el-dialog>
    <el-dialog
      :close-on-click-modal="false"
      :before-close="cancelCU"
      :visible.sync="simpleFlag"
      title="验证脱敏函数"
      width="800px"
      append-to-body
    >
      <el-table
        ref="table"
        v-loading="simpleDataLoading"
        :data="simpleData"
        border
        max-height="300px"
        style="margin-top: 15px"
      >
        <el-table-column
          label="原数据"
          prop="oldData"
        />
        <el-table-column
          label="脱敏后数据"
          prop="newData"
        />
      </el-table>
    </el-dialog>
    <el-dialog
      :close-on-click-modal="false"
      :before-close="rulelCU"
      :visible.sync="showDesensitizationRulesFlag"
      title="脱敏函数清单"
      width="1200px"
      append-to-body
    >
      <desensitization-rules ref="ruleReset"/>
    </el-dialog>
    <el-dialog
      v-if="showDesensitizationBlackFlag"
      :close-on-click-modal="false"
      :before-close="cancelCU"
      :visible.sync="showDesensitizationBlackFlag"
      title="脱敏黑名单"
      width="1000px"
      append-to-body
    >
      <desensitization-black-list ref="rulesReset"/>
    </el-dialog>
    <el-dialog
      v-if="showDesensitizationMapFlag"
      :close-on-click-modal="false"
      :before-close="cancelCU"
      :visible.sync="showDesensitizationMapFlag"
      title="脱敏函数与字段映射清单"
      width="1200px"
      append-to-body
    >
      <desensitization-maps ref="rulesReset"/>
    </el-dialog>
  </div>
</template>

<script>
import CRUD, {presenter, header, form, crud} from '@crud/crud'
import rrOperation from '@crud/RR.operation'
import pagination from '@crud/Pagination'
import desensitizationFieldsTask, {findListByPage} from '@/api/dashboard/desensitizationFieldsTask'
import crudOperation from '@crud/CRUD.operation.vue'
import hiveMetadataApi from '@/api/dataTransfer/common/hiveMetadata'
import desensitizeFunctionApi from '@/api/dashboard/desensitizeFunction'
import desensitizationRules from '.././desensitizationRules/index'
import desensitizationMaps from '.././desensitizationMaps/index'
import desensitizationBlackList from '.././desensitizationBlackList/index'

// crud交由presenter持有
const defaultCrud = CRUD({
  title: '数据脱敏字段配置',
  url: '/api/desensitizefieldlist/page',
  crudMethod: {...desensitizationFieldsTask}
})
const defaultForm = {
  id: null,
  functionId: null,
  dbName: null,
  tableName: null,
  fieldName: null,
  desensitizeFunction: null
}
export default {
  name: 'DataDesensitizationFields',
  components: {crudOperation, rrOperation, pagination, desensitizationRules, desensitizationMaps, desensitizationBlackList },
  mixins: [presenter(defaultCrud), header(), form(defaultForm), crud()],
  data() {
    return {
      resetting: false,
      simpleDataLoading: false,
      permission: {
        add: ['admin', 'scriptPack:add'],
        del: ['admin', 'scriptPack:del']
      },
      showDesensitizationRulesFlag: false,
      showDesensitizationBlackFlag: false,
      showDesensitizationMapFlag: false,
      disableLoading: false,
      databaseList: [],
      tableList: [],
      functionList: [],
      fieldList: [],
      fileList: [],
      simpleFlag: false,
      simpleData: [],
      simpleDataLoading: false,
      desensitizationFuncationList: [],
      rules: {
        fieldName: [
          {required: true, message: '请输入脱敏字段', trigger: 'blur'}
        ],
        functionId: [
          {required: true, message: '请选择脱敏函数', trigger: 'change'}
        ],
        desensitizeFunction: [
          {required: true, message: '请输入脱敏函数样例', trigger: 'blur'}
        ]
      }
    }
  },
  created() {
    this.initData()
    this.initQueryData()
  },
  methods: {
    async reset() {
      this.resetting = true
      await desensitizationFieldsTask.reset().then(res => {
        this.resetting = false
        this.$notify({title: '刷新成功', type: 'success'})
        this.crud.refresh()
      })
    },
    initData() {
      this.initAllFunctionList()
    },
    // 初始化获取所有的脱敏函数列表
    initAllFunctionList() {
      const param = {size: 10000000}
      desensitizeFunctionApi.findListByPage(param).then(res => {
        if (res.totalElements > 0) {
          this.desensitizationFuncationList = res.content
        }
      })
    },
    initQueryData() {
      desensitizationFieldsTask.findList().then(res => {
        const databaseList = [...new Set(res.map(item => item.dbName))].sort()
        const tableList = [...new Set(res.map(item => item.tableName))].sort()
        const functionList = [...new Set(res.map(item => item.desensitizeFunction))].sort()
        const fieldList = [...new Set(res.map(item => item.fieldName))].sort()
        this.databaseList = databaseList
        this.tableList = tableList
        this.functionList = functionList
        this.fieldList = fieldList
      })
    },
    showDesensitizationFuncation() {
      this.showDesensitizationRulesFlag = true
    },
    showDesensitizationBlackFuncation() {
      this.showDesensitizationBlackFlag = true
    },
    showDesensitizationMap() {
      this.showDesensitizationMapFlag = true
    },
    functionNameChange(functionId) {
      let functionObject = null
      this.desensitizationFuncationList.forEach(item => {
        if (functionId === item.id) {
          functionObject = JSON.parse(JSON.stringify(item))
        }
      })
      this.form.desensitizeFunction = functionObject.functionDetails.replace('field_name', this.form.fieldName)
    },
    toDelete(datas) {
      this.$confirm(`确认禁用选中的${datas.length}条脱敏字段?`, '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      })
        .then(() => {
          this.disableLoading = true
          this.disable(datas)
        })
        .catch(() => {
        })
    },
    disable(data) {
      const ids = []
      if (data instanceof Array) {
        data.forEach(val => {
          ids.push(val.id)
        })
      } else {
        ids.push(data.id)
      }
      desensitizationFieldsTask.disable(ids).then(res => {
        this.disableLoading = false
        this.$notify({title: '禁用成功', type: 'success'})
        this.crud.refresh()
      }).catch(() => {
        this.disableLoading = false
      })
    },
    toShowSimple(row) {
      this.simpleFlag = true
      const paramData = {
        databaseName: row.dbName,
        tableName: row.tableName,
        fieldName: row.fieldName,
        functionDetails: row.desensitizeFunction
      }
      this.simpleDataLoading = true
      this.simpleData = []
      hiveMetadataApi.funcationTest(paramData).then(res => {
        this.simpleDataLoading = false
        this.simpleData = res
      }).catch(err => {
        this.simpleDataLoading = false
      })
    },
    rulelCU() {
      this.$refs.ruleReset.crud.resetQuery(true)
      this.simpleFlag = false
      this.showDesensitizationRulesFlag = false
      this.showDesensitizationMapFlag = false
      this.showDesensitizationBlackFlag = false
      this.initQueryData()
      this.crud.refresh()
    },
    cancelCU() {
      this.$refs.rulesReset.crud.resetQuery(true)
      this.simpleFlag = false
      this.showDesensitizationRulesFlag = false
      this.showDesensitizationMapFlag = false
      this.showDesensitizationBlackFlag = false
      this.initQueryData()
      this.crud.refresh()
    }
  }
}
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
/deep/ .el-icon-upload {
  font-weight: 400;
  line-height: 1 !important;
  font-size: 12px !important;
}
</style>
